package com.upcoming.container;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.common.utils.ConfigUtils;
import com.alibaba.dubbo.container.Container;
import com.upcoming.deploy.DeployEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.management.ManagementFactory;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * dubbo 服务入口
 */
public class Main {

    private static final String CONTAINER_KEY = "container";

    private static final String SHUTDOWN_HOOK_KEY = "shutdown.hook";

    private static final Logger logger = LoggerFactory.getLogger(Main.class);

    private static ExtensionLoader<Container> loader = ExtensionLoader.getExtensionLoader(Container.class);

    private static volatile boolean running = true;

    public static void main(String[] args) {

        System.setProperty(CONTAINER_KEY, "springContainer");

        //初始化环境变量
        DeployEnvironment.initialize();

        if (args == null || args.length == 0) {
            String config = ConfigUtils.getProperty(CONTAINER_KEY, loader.getDefaultExtensionName());
            args = Constants.COMMA_SPLIT_PATTERN.split(config);
        }
        final List<Container> containers = new ArrayList<>();
        for (int i=0; i < args.length; i++) {
            containers.add(loader.getExtension(args[i]));
        }
        logger.info("[事件]容器启动.使用容器服务启动服务 " + Arrays.toString(args));

        if ("true".equals(System.getProperty(SHUTDOWN_HOOK_KEY))) {
            Runtime.getRuntime().addShutdownHook(new Thread(){
                @Override
                public void run() {
                    for (Container container : containers) {
                        try {
                            container.stop();
                            logger.info("容器[" + container.getClass().getSimpleName()+ "]关闭");
                        } catch (Throwable t) {
                            logger.error(t.getMessage(), t);
                        }
                        //通知
                        synchronized (Main.class) {
                            Main.class.notify();
                            running = false;
                        }
                    }
                }
            });
        }

        //启动容器
        for (Container container : containers) {
            try {
                logger.info("容器启动。[" + container.getClass().getSimpleName() + "] 开始启动！");
                container.start();
                logger.info("容器启动。[" + container.getClass().getSimpleName() +
                        new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]").format(new Date()) + "] 已经启动！");
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }

        logger.info("**********************************************************");
        logger.info("进程：" + ManagementFactory.getRuntimeMXBean().getName());
        logger.info("可用的处理器数：" + Runtime.getRuntime().availableProcessors() +
                " totalMoney:" + (Runtime.getRuntime().totalMemory() >> 20));

        //主线程等等
        try {
            synchronized (Main.class) {
                //主线程死循环
                while (running) {
                    Main.class.wait();
                    System.out.println("running ...");
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

    }
}
